#ifndef __PTGUI_LIST_H__
#define __PTGUI_LIST_H__

#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)

struct ptgui_list_node
{
	struct ptgui_list_node	*next;
};

typedef struct ptgui_list_node ptgui_list_t;

void ptgui_list_init(struct ptgui_list_node *l);
void ptgui_list_append(struct ptgui_list_node *l, struct ptgui_list_node *n);

void ptgui_list_insert(struct ptgui_list_node *l, struct ptgui_list_node *n);
struct ptgui_list_node *ptgui_list_remove(struct ptgui_list_node *l, struct ptgui_list_node *n);	 

#define ptgui_list_entry(node, type, member)	\
	PTGIO_CONTAINER_OF(node, type, member)

#define ptgui_list_foreach(node, list)	\
	for ((node) = (list)->next; (node) != NULL; (node) = (node)->next)

struct ptgui_dlist_node
{
	struct ptgui_dlist_node	*next;
	struct ptgui_dlist_node	*prev;
};
typedef struct ptgui_dlist_node ptgui_dlist_t;

#define PTGUI_DLIST_HEAD_INIT(name) { &(name), &(name) }
#define PTGUI_DLIST_HEAD(name) \
	struct ptgui_dlist_node name = PTGUI_DLIST_HEAD_INIT(name)
#define PTGUI_INIT_LIST_HEAD(ptr) do { \
		(ptr)->next = (ptr); (ptr)->prev = (ptr); \
	} while (0)

void ptgui_dlist_add(struct ptgui_dlist_node *new, struct ptgui_dlist_node *head);
void ptgui_dlist_add_tail(struct ptgui_dlist_node *new, struct ptgui_dlist_node *head);
void ptgui_dlist_del(struct ptgui_dlist_node *entry);
void ptgui_dlist_del_init(struct ptgui_dlist_node *entry);
void ptgui_dlist_move(struct ptgui_dlist_node *list, struct ptgui_dlist_node *head);
void ptgui_dlist_move_tail(struct ptgui_dlist_node *list, struct ptgui_dlist_node *head);
int ptgui_dlist_empty(const struct ptgui_dlist_node *head);
int ptgui_dlist_empty_careful(const struct ptgui_dlist_node *head);
void ptgui_dlist_splice(struct ptgui_dlist_node *list, struct ptgui_dlist_node *head);
void ptgui_dlist_splice_init(struct ptgui_dlist_node *list, struct ptgui_dlist_node *head);

#define ptgui_dlist_entry(ptr, type, member) \
	PTGIO_CONTAINER_OF(ptr, type, member)
#define ptgui_dlist_for_each(pos, head) \
	for (pos = (head)->next; pos != (head); pos = pos->next)
#define ptgui_dlist_for_each_prev(pos, head) \
	for (pos = (head)->prev; pos != (head); pos = pos->prev)

#define ptgui_dlist_for_each_safe(pos, n, head) \
	for (pos = (head)->next, n = pos->next; pos != (head); \
	   pos = n, n = pos->next)

struct ptgui_hlist_head
{
	struct ptgui_hlist_node	*first;
};

struct ptgui_hlist_node
{
	struct ptgui_hlist_node	*next,
							 **pprev;
};
typedef struct ptgui_hlist_node ptgui_hlist_t;

#define PTGUI_HLIST_HEAD_INIT { .first = NULL }
#define PTGUI_HLIST_HEAD(name) struct ptgui_hlist_node name = { .first = NULL }
#define PTGUI_INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
#define PTGUI_INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)

int ptgui_hlist_unhashed(const struct ptgui_hlist_node *h);
int ptgui_hlist_empty(const struct ptgui_hlist_head *h);
void __ptgui_hlist_del(struct ptgui_hlist_node *n);
void ptgui_hlist_del(struct ptgui_hlist_node *n);
void ptgui_hlist_del_init(struct ptgui_hlist_node *n);

void ptgui_hlist_add_head(struct ptgui_hlist_node *n, struct ptgui_hlist_head *h);
void ptgui_hlist_add_before(struct ptgui_hlist_node *n, struct ptgui_hlist_node *next);
void ptgui_hlist_add_after(struct ptgui_hlist_node *n, struct ptgui_hlist_node *next);
#define ptgui_hlist_entry(ptr, type, member) \
	PTGIO_CONTAINER_OF(ptr,type,member)
#define ptgui_hlist_for_each(pos, head) \
	for (pos = (head)->first; pos != ptgui_NULL; pos = pos->next)
#define ptgui_hlist_for_each_safe(pos, n, head) \
	for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
		  pos = n)

#endif	//__PTGUI_LIST_H__
